#ifndef PUBLIC_H
#define PUBLIC_H
#include <stdint.h>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
#include <map>
#include <sstream>
#include <boost/bind.hpp>
#include <boost/smart_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/format.hpp>
#include <boost/signals2.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/foreach.hpp>

#include <boost/archive/iterators/ostream_iterator.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>


#include <curl/curl.h>
#include <libconfig.h++>

#include <log4cpp/Category.hh>
#include <log4cpp/OstreamAppender.hh>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/BasicLayout.hh>
#include <log4cpp/Priority.hh>
#include <log4cpp/PropertyConfigurator.hh>
#include <log4cpp/Configurator.hh>
#include <log4cpp/PatternLayout.hh>
#include <log4cpp/NDC.hh>
#include <log4cpp/SimpleLayout.hh>


using namespace std;
using boost::bind;
using boost::format;
using boost::thread;
using boost::lexical_cast;

#define DEBUG_OUTPUT(msg)\
do{\
cerr << format("%s %d@%s : %s") % __func__ % __LINE__ %  __FILE__ % msg << endl;\
}while(false)

const static unsigned KB = 1 << 10;
const static unsigned MB = KB << 10;
const static unsigned GB = MB << 10;
//const static uint64_t TB = GB << 10;

const static unsigned MAX_URL_LENGTH = 1 << 10;

struct Task;

struct DownloadInfo{
	Task* task; //raw point, do not release it!!!
	CURL* handle;
	string url;		//the url user input
	string realUrl;		//the real url that the resource locates, for thunder, flashget, ......
	
	unsigned threadIndex;

	uint64_t bytesFrom;
	uint64_t bytesTo;
	
	unsigned lastPieceRecved;
	uint64_t bytesRecved;
	uint64_t bytesTotal;
	FILE* output;
	unsigned pieceSize;
	unsigned deltaOffset;
};
typedef boost::shared_ptr<DownloadInfo> DownloadInfoPtr;
typedef boost::shared_ptr<thread> ThreadPtr;

struct Task{
	size_t id;
	string name;
	string url;	
	string realUrl;
	string fromUrl;
	string filename;
	string localPath;
	size_t threadCount;
	bool breakpointSupport;
	double fileSize;
	vector<DownloadInfoPtr> dis;
};
typedef boost::shared_ptr<Task> TaskPtr;

struct ProgressInfo{
	CURL* handle;
	double lastTime;
	double lastBytes;
};
class ThreadPool{
	public:
		int get_thread(ThreadPtr& t)
		{
			return 0;
		}
};
struct Config{
	Config(const string& configFilename)
	{
		
	}
	size_t speedLimit;
	size_t bytesPerTime;
	string proxyString;
};

log4cpp::Category* logger = NULL;
boost::thread_specific_ptr<long> pLastPort;

#endif
